﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;


namespace treadmillProject.src.model {
    public class TrainingSession {
        public static List<TrainingData> trainingData = new List<TrainingData>();

        public delegate void delegate_func(TrainingData td);

        private delegate_func deltest;
        private Client client = new Client();

        private static TrainingSession ts = null;

        public static TrainingSession accessTrS() {
            if (ts == null) {
                ts = new TrainingSession();
            }
            return ts;
        }


        private TrainingSession() {
            //  Console.WriteLine("TrainingSession init...");

            deltest = new delegate_func(graph_updates);
        }

        public void resetTrainingData() {
            trainingData.Clear();
            Pulse.MaxPulse = 0;
            Speed.MaxSpeed = 0;
            Gear.MaxGear = 0;
        }


        public void graph_updates(TrainingData bd) {
            //g1.func(bd);
            Console.WriteLine("graph_updates");
        }

        public TrainingData recv() {
            String str = "";
            TrainingData dataw = null;


            try {
                str = client.getNextLine();
                Console.WriteLine("DAAAAAAAAAAAAAAAAAAAAAAAAAAM: " + str);

                if (str.Equals("b")) {
                    //       client.client_end();
                    dataw = null;
                } else {
                    TrainingData td = parseComObject(str);

                    if (td != null) {
                        dataw = td;
                        trainingData.Add(dataw);
                        deltest(trainingData[trainingData.Count() - 1]);

                        Console.WriteLine("OBJECT " + (trainingData.Count() - 1) + " : ");

                        Console.WriteLine("" + trainingData[trainingData.Count() - 1].ToString());
                    }
                    //dataw = parseComObject(str);

                    //        _source.AppendAsync(Dispatcher, dataw);
                }
            } catch (Exception e) {
                Console.WriteLine("STRIIIIIIiiiiiiiiiiiiiiiIING: " + str);
                //return dataw;
            }
            return dataw;
        }

        public void sendStart() {
            client.sendstart();
        }

        public void sendStop() {
            client.sendstop();
        }

        public void EndConnection() {
            client.client_end();
        }


        public void InitiateConnection() {
            client.clientInit();
        }


        public TrainingData parseComObject(String str) {
            if (str.Contains("<s")) {
                int speed, pulse, gear;
                //******************************************************
                //EXTRACTING SPEED
                int index_of_speed = str.IndexOf("<s");
                int index_of_speend_end = str.IndexOf(">");
                int diff_speed = index_of_speend_end - (index_of_speed + 2);
                //SPEED:
                string speedStr = str.Substring(index_of_speed + 2, diff_speed);

                speed = Convert.ToInt32(speedStr);
                //*****************************************************

                //******************************************************
                //EXSTRACTING PULSE
                string temp = str.Substring(index_of_speend_end + 1);
                int index_of_pulse = temp.IndexOf("<p");
                int index_of_pulse_end = temp.IndexOf(">");
                int diff_pulse = index_of_pulse_end - (index_of_pulse + 2);
                string pulseStr = temp.Substring(index_of_pulse + 2, diff_pulse);
                pulse = Convert.ToInt32(pulseStr);
                //*****************************************************

                //******************************************************
                //EXSTRACTING GEAR
                string temp2 = temp.Substring(index_of_pulse_end + 1);
                int index_of_gear = temp2.IndexOf("<g");
                int index_of_gear_end = temp2.IndexOf(">");
                int diff_gear = index_of_gear_end - (index_of_gear + 2);
                string gearStr = temp2.Substring(index_of_gear + 2, diff_gear);
                gear = Convert.ToInt32(gearStr);
                //*****************************************************

                TrainingData trainingDataTemp = new TrainingData(new Pulse(pulse), new Speed(speed), new Gear(gear));

                return trainingDataTemp;
            } else {
                return null;
            }
        }

        public void Store(String fileName) {
            Stream myStream = File.Open(fileName, FileMode.Create);
            BinaryFormatter bFormatter = new BinaryFormatter();

            Console.WriteLine("TEST SAVING");
            bFormatter.Serialize(myStream, trainingData);
            myStream.Close();
        }


        public void ReStore(String fileName) {
            trainingData.Clear();

            Stream myStream = File.Open(fileName, FileMode.Open);
            BinaryFormatter bFormatter = new BinaryFormatter();
            Console.WriteLine("Restoring...");

            try {
            } catch (Exception e) {
                Console.WriteLine(e.StackTrace);
                Console.WriteLine("Shit happens");
            }

            trainingData = (List<TrainingData>) bFormatter.Deserialize(myStream);
            myStream.Close();

            for (int i = 0; i < trainingData.Count(); i++) {
                Console.WriteLine("OBJECT " + i + " : ");

                Console.WriteLine("" + trainingData[i].ToString());
            }
        }
    }
}